package com.relax.netty.nio;

import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class TestNio {

    public static void main(String[] args) throws Exception {
        FileInputStream file = new FileInputStream("a.txt");
        FileChannel channel = file.getChannel();

        //初始化Buffer的长度为5,即使文件里面有多个元素,也只能读5个数据
        ByteBuffer byBuf = ByteBuffer.allocate(5);
        //buff的pos从0开始,limit是allocate初始化大小的(由于buf下表是从0开始的)5,channel的pos表示通道里面的文件读取数据的位置,也为0
        System.out.println("step1: byBufPosition:" + byBuf.position() + ",byBufLimit:" + byBuf.limit() + ",channelPosition:" + channel.position());
        //channel读取数据,即往Buffer里面写数据
        channel.read(byBuf);
        //在Buffer里面写完5个数据之后,buff的pos位置是5,byLimit的位置仍然是原来的位置5,由于读取文件读到了5个元素，所以chnanle的pos是5.
        System.out.println("step2: byBufPosition:" + byBuf.position() + ",byBufLimit:" + byBuf.limit() + ",channelPosition:" + channel.position());
        //将Buff的写状态转换为读状态,重置pos和limit,但是和channel没有关系。并没有重置channel
        byBuf.flip();
        //重置后,从0开始读取,最大可读的数量为5(里面只有5个元素),channel的pos不变
        System.out.println("step3: byBufPosition:" + byBuf.position() + ",byBufLimit:" + byBuf.limit() + ",channelPosition:" + channel.position());
        while (byBuf.remaining() > 0) {
            byte b = byBuf.get();
            System.out.println("Chanrset:" + (char) b);
        }
        //读取完之后Buf的pos及limit移动值
        System.out.println("step4: byBufPosition:" + byBuf.position() + ",byBufLimit:" + byBuf.limit() + ",channelPosition:" + channel.position());
        //再次重置,将Buf的读转换为往Buff里面写.
        byBuf.flip();
        //buff的pos被重置为0,buf的Limit被重置为上次最大可读取数据的位置,即step4的pos位置,由于和channel没有关系。所以channel的pos不变认为5
        System.out.println("step5: byBufPosition:" + byBuf.position() + ",byBufLimit:" + byBuf.limit() + ",channelPosition:" + channel.position());
        //在此读取数据,即往Buff里面写数据
        channel.read(byBuf);
        //由于channel的pos是5，里面有8个元素，上次读了5个剩余3个,所以在读完之后,pos的位置是3,，limit仍然保留上次的值5，channel的位置移动,移动到8
        System.out.println("step6: byBufPosition:" + byBuf.position() + ",byBufLimit:" + byBuf.limit() + ",channelPosition:" + channel.position());
        byBuf.flip();
        //由Buff的写数据转换为读数据,buf的pos被初始化为0,,limit被设置为最大可读取的位置,即step6的pos配置3.channel的pos是8
        System.out.println("step7: byBufPosition:" + byBuf.position() + ",byBufLimit:" + byBuf.limit() + ",channelPosition:" + channel.position());
        while (byBuf.remaining() > 0) {
            byte b = byBuf.get();
            System.out.println("Chanrset:" + (char) b);
        }

        //通过step4--step5和step6--step7可看出buf的limi是上一次pos的位置，不管是读还是写。即将要读或者写的最后一个元素的下一个元素的索引位置
        channel.close();
    }

}